const { ModuleFederationPlugin } = require("webpack").container;
const { assemble, depend, pipe } = require("webpack-pipe");
const CopyWebpackPlugin = require("copy-webpack-plugin");

/**
 * 组装webpack config
 * @return {*}
 */
module.exports = {
    webpackConfParams:{},
    formatWebpackConf: (config, isProdMode) => {
        return assemble([
            pipe.styledJsx,
            setVendor,
            setModuleFederationPlugin,
            setMonacoEditor,
            setThreeJS,
            setCesiumPlugin,
            setJessibucaPlayer,
            setReactSvg,
            setTailWindCSS,
            () => config
        ]);
    }
};

/**
 * 设置vendor
 */
const setVendor = (config) => {
    config.resolve.alias = {
        ...config.resolve.alias,
        "vendor": depend.tool.resolveAppPath("../vendor"),
    };

    return config;
}

/**
 * 设置联邦模块
 */
const setModuleFederationPlugin = (config) => {
    const deps = require("../../package.json").dependencies;

    config.plugins.push(new ModuleFederationPlugin({
        name: "app",
        filename: "remoteEntry.js",
        exposes: {
            // "./app": "./src/App",
        },
        shared: {
            react: {
                singleton: true,
                requiredVersion: deps.react
            },
            "react-dom": {
                singleton: true,
                requiredVersion: deps["react-dom"]
            },
        }
    }))

    return config;
}


/**
 * 支持tailWindCSS
 */
const setTailWindCSS = (config) => {
    config.module.rules.map((rule) =>{
        if(rule.test && rule.test.test(".css")){
            rule.use[2].options.postcssOptions.plugins.push(['tailwindcss'])
            rule.use[2].options.postcssOptions.plugins.push(['autoprefixer'])
        }
    })

    return config;
}



/**
 * 支持svg react组件
 */
const setReactSvg = (config) => {
    // npm install @svgr/webpack --save-dev
    config.module.rules.map((rule) =>{
        if(rule.test && rule.test.test(".svg")){
            rule.exclude = [
                /\/src\/icon\/img/,
                /\\src\\icon\\img/,     // 兼容windows
            ]
        }
    });

    config.module.rules.push({
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        include:[
            /\/src\/icon\/img/,
            /\\src\\icon\\img/,     // 兼容windows
        ],
        use: [
            {
                loader: 'babel-loader',
            },
            {
                loader: '@svgr/webpack',
                options: {
                    babel: true,
                    icon: true,
                },
            },
        ],
    });

    return config;
}


/**
 * 设置处理monaco-editor
 */
const setMonacoEditor = (config) => {
    const path = require("path");
    const { merge } = depend;

    const monacoEditorSource = '../../vendor/node_modules/monaco-editor';

    return merge({
        plugins: [
            new CopyWebpackPlugin({
                patterns:[
                    { from: path.join(__dirname,monacoEditorSource, 'min/vs'), to: "vs" },
                ]
            })
        ]
    }, config || {});
};

/**
 * 设置处理three.js
 */
const setThreeJS = (config) => {
    const path = require("path");
    const { merge } = depend;
    const baseSource = '../../vendor/node_modules/three';

    return merge({
        plugins: [
            new CopyWebpackPlugin({
                patterns:[
                    { from: path.join(__dirname,baseSource, 'examples/jsm/libs/draco'), to: "three/draco" },
                ]
            })
        ]
    }, config || {});
};


/**
 * 设置处理cesium
 */
const setCesiumPlugin = (config) => {
    const path = require("path");
    const { merge, webpack } = depend;

    const cesiumSource = '../../vendor/node_modules/cesium/Source';
    const cesiumBuild = '../../vendor/node_modules/cesium/Build';

    return merge({
        module: {
            rules: [
                {
                    test: /\.(glsl)$/,
                    use: ['raw-loader']
                }
            ]
        },
        resolve:{
            alias:{
                cesiumSource: path.resolve(__dirname, cesiumSource),
                cesium: path.resolve(__dirname, cesiumSource, "Cesium.js")
            },
            fallback: {
                https: false,
                http: false,
                zlib: false,
                url: false,
                buffer: false,
                assert: false,
                util: false,
                stream: false,
            }
        },
        amd: {
            // Enable webpack-friendly use of require in Cesium
            toUrlUndefined: true
        },
        output: {
            sourcePrefix: "",
        },
        plugins: [
            new webpack.DefinePlugin({
                // Define relative base path in cesium for loading assets
                // CESIUM_BASE_URL: process.env.NODE_ENV == 'production' ? JSON.stringify('/static') : JSON.stringify('/public')
                // CESIUM_BASE_URL: JSON.stringify('')
            }),

            new CopyWebpackPlugin({
                patterns:[
                    { from: path.join(__dirname,cesiumBuild, 'Cesium/Workers'), to: "Workers" },
                    { from: path.join(__dirname,cesiumBuild, 'Cesium/Assets'), to: "Assets" },
                    { from: path.join(__dirname,cesiumBuild, 'Cesium/Widgets'), to: "Widgets" },
                    { from: path.join(__dirname,cesiumBuild, 'Cesium/ThirdParty'), to: "ThirdParty" }
                ]
            })
        ]

    }, config || {});
};


/**
 * 设置处理jessibuca-player
 */
const setJessibucaPlayer = (config) => {
    const path = require("path");
    const { merge } = depend;

    const jessibucaSource = '../../vendor/components/pro-jessibuca/jessibuca';

    return merge({
        plugins: [
            new CopyWebpackPlugin({
                patterns:[
                    { from: path.join(__dirname,jessibucaSource), to: "jessibuca" },
                ]
            })
        ]
    }, config || {});
};

// /**
//  * 支持语法less
//  * @param config
//  * @returns {*}
//  */
// const setLess = (config) => {
//     // npm install less less-loader
//     config.module.rules.push({
//         test: /\.less/,
//         use: depend.formatStyleLoader({
//             loader: 'less-loader',
//             options: {
//                 lessOptions: {
//                     modifyVars: {},
//                     javascriptEnabled: true,
//                 },
//                 sourceMap: process.env.NODE_ENV === "production" ? false : true,
//             }
//         })
//     });
//
//     // config.module.rules = config.module.rules.map(rule => {
//     //     if (rule.loader === "babel-loader"){
//     //         // `style: true` for less
//     //         // babel-plugin-import
//     //         rule.options.plugins.push(['import', {libraryName: 'antd', 'libraryDirectory': 'es', style: true}]);
//     //
//     //         return rule;
//     //     }
//     //
//     //     return rule;
//     // });
//
//     return config;
// }